package org.tio.sitexxx.service.service.tiosite;

import java.sql.SQLException;
import java.util.Date;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.tio.sitexxx.service.cache.CacheConfig;
import org.tio.sitexxx.service.cache.Caches;
import org.tio.sitexxx.service.model.main.Blog;
import org.tio.sitexxx.service.model.main.BlogContent;
import org.tio.sitexxx.service.model.main.BloglogAccess;
import org.tio.sitexxx.service.model.main.IpInfo;
import org.tio.sitexxx.service.model.main.User;
import org.tio.sitexxx.service.model.main.UserAgent;
import org.tio.sitexxx.service.service.base.IpInfoService;
import org.tio.sitexxx.service.service.base.UserAgentService;
import org.tio.sitexxx.service.service.base.UserService;
import org.tio.sitexxx.service.topic.Topics;
import org.tio.sitexxx.service.vo.Const;
import org.tio.utils.cache.CacheUtils;
import org.tio.utils.cache.FirsthandCreater;
import org.tio.utils.cache.ICache;

import com.jfinal.kit.Kv;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Page;
import com.jfinal.plugin.activerecord.Record;
import com.jfinal.plugin.activerecord.SqlPara;

/**
 * @author tanyaowu
 * 2016年7月22日 上午10:44:55
 */
public class BlogService {
	@SuppressWarnings("unused")
	private static Logger			log	= LoggerFactory.getLogger(BlogService.class);
	public static final BlogService	me	= new BlogService();
	private final Blog				dao	= new Blog().dao();

	/**
	 *
	 * @author tanyaowu
	 */
	public BlogService() {
	}

	/**
	 * 分页查询列表
	 * @param pageNumber
	 * @param pageSize
	 * @param uid
	 * @return
	 */
	public Page<Record> page(int pageNumber, int pageSize, Integer uid) {
		Kv params = Kv.by("uid", uid);
		SqlPara sqlPara = dao.getSqlPara("blog.page", params);
		Page<Record> ret = Db.use(Const.Db.TIO_SITE_MAIN).paginate(pageNumber, pageSize, sqlPara);
		
		List<Record> list = ret.getList();
		if (list != null) {
			for (Record record : list) {
				Integer bloguid = record.getInt("uid");
				if (bloguid != null) {
					User user = UserService.ME.getById(bloguid);
					record.set("nick", user.getNick());
					record.set("avatar", user.getAvatar());
					record.set("roles", user.getRoles());
				}
			}
		}
		return ret;
	}

	/**
	 * 保存博客
	 * @param blog
	 * @param blogContent 
	 * @return
	 */
	public boolean save(Blog blog, BlogContent blogContent) {
		return Db.tx(() -> {
			boolean f = blog.save();
			if (f) {
				blogContent.setBlogid(blog.getId());
				boolean f2 = blogContent.save();
				if (f2) {
					clearCache(blog.getId());
					return true;
				} else {
					return false;
				}
			} else {
				return false;
			}
			//			return true;
		});
	}

	/**
	 * 更新博客
	 * @param blog
	 * @return
	 * @throws SQLException
	 */
	public boolean update(Blog blog, BlogContent blogContent) throws SQLException {
		return Db.tx(() -> {
			boolean f = blog.update();
			if (f) {
				blogContent.setBlogid(blog.getId());
				boolean f2 = blogContent.update();
				if (f2) {
					clearCache(blog.getId());
					return true;
				} else {
					return false;
				}
			} else {
				return false;
			}
		});

	}

	/**
	 * 分页查询某用户的博客列表
	 * @param uid
	 * @param pageNumber
	 * @param pageSize
	 * @return
	 */
	public Page<Blog> pageByUid(int uid, int pageNumber, int pageSize) {
		User user = UserService.ME.getById(uid);
		if (user == null) {
			return null;
		}

		SqlPara sqlPara = Db.use(Const.Db.TIO_SITE_MAIN).getSqlPara("blog.pageByUid", uid);
		Page<Blog> page = dao.paginate(pageNumber, pageSize, sqlPara);
		return page;
	}

	/**
	 * 查询某用户的所有博客id
	 * @param uid
	 * @return
	 */
	public static List<Integer> getByUid(Integer uid) {
		String sql = "select id from blog where uid = ?";
		List<Integer> list = Db.use(Const.Db.TIO_SITE_MAIN).query(sql, uid);

		return list;
	}

	/**
	 * 查询数据用于生成sitemap
	 * @return
	 */
	public static List<Record> getForSitemap() {
		String sql = "select id, updatetime from blog where status = ? and open = 1 order by updatetime desc limit 49990";
		List<Record> list = Db.use(Const.Db.TIO_SITE_MAIN).find(sql, Blog.Status.OK);

		return list;
	}

	/**
	 * 根据博客id进行查询
	 * @param id
	 * @return
	 */
	public Blog getById(Integer id) {
		if (id == null) {
			return null;
		}

		String key = id + "";
		ICache cache = Caches.getCache(CacheConfig.BLOG);
		Blog blog = CacheUtils.get(cache, key, true, new FirsthandCreater<Blog>() {
			@Override
			public Blog create() {
				Blog blog = dao.findById(id);
				return blog;
			}
		});
		return blog;
	}

	/**
	 * 会带上title, md
	 * @param id
	 * @return
	 */
	public Record getByIdWithMd(Integer id) {
		if (id == null) {
			return null;
		}

		String key = id + "";
		ICache cache = Caches.getCache(CacheConfig.BLOG_WITH_MD);
		Record record = CacheUtils.get(cache, key, true, new FirsthandCreater<Record>() {
			@Override
			public Record create() {
				SqlPara sqlPara = Db.use(Const.Db.TIO_SITE_MAIN).getSqlPara("blog.getByIdWithMd", id);
				Record record = Db.findFirst(sqlPara);
				//				Blog blog = dao.findFirst(sqlPara);
				return record;
			}
		});
		return record;
	}

	/**
	 * 保存博客访问日志
	 * @param initblogid
	 * @param blogid
	 * @param session
	 * @param uid
	 * @param userAgent
	 * @param clientIp
	 * @param referer
	 * @author tanyaowu
	 */
	public void saveAccessLog(Integer initblogid, Integer blogid, String session, Integer uid, String userAgent, String clientIp, String referer) {
		BloglogAccess bloglogAccess = new BloglogAccess();
		bloglogAccess.setBlogid(initblogid);
		bloglogAccess.setShowblogid(blogid);
		bloglogAccess.setSession(session);
		bloglogAccess.setUid(uid);
		bloglogAccess.setReferer(referer);
		bloglogAccess.setTime(new Date());

		UserAgent ua = UserAgentService.ME.save(userAgent);
		bloglogAccess.setUaid(ua.getId());

		IpInfo ipInfo = IpInfoService.ME.save(clientIp);

		bloglogAccess.setIpid(ipInfo.getId());
		bloglogAccess.save();
	}

	/**
	 * 获取博客访问次数
	 * @param blogid
	 * @return
	 * @author tanyaowu
	 */
	public Integer getAccessCount(Integer blogid) {
		if (blogid == null) {
			return 0;
		}
		String key = blogid + "";
		ICache cache = Caches.getCache(CacheConfig.BLOG_ACCESSCOUNT);
		Integer count = CacheUtils.get(cache, key, true, new FirsthandCreater<Integer>() {
			@Override
			public Integer create() {
				String sql = "select count(*) from bloglog_access where blogid = ?";
				Integer count = Db.use(Const.Db.TIO_SITE_MAIN).queryInt(sql, blogid);
				return count;
			}
		});
		if (count == null) {
			return 0;
		}
		count++;
		cache.put(key, count);
		return count;
	}

	/**
	 * 会带上title, html
	 * @param id
	 * @return
	 */
	public Record getByIdWithHtml(Integer id) {
		if (id == null) {
			return null;
		}

		String key = id + "";
		ICache cache = Caches.getCache(CacheConfig.BLOG_WITH_HTML);
		Record record = CacheUtils.get(cache, key, true, new FirsthandCreater<Record>() {
			@Override
			public Record create() {
				SqlPara sqlPara = Db.use(Const.Db.TIO_SITE_MAIN).getSqlPara("blog.getByIdWithHtml", id);
				Record record = Db.findFirst(sqlPara);
				//				Blog blog = dao.findFirst(sqlPara);
				return record;
			}
		});
		return record;
	}

	/**
	 * 
	 * @param blogid 博客id
	 */
	public static void clearCache(Integer blogid) {
		//		//清除api缓存
		//		Map<String, Object> param = new HashMap<>();
		//		param.put("id", id);
		//		String path = "/blog/getById";
		//		Topics.notifyClearHttpCache(path, null, param);
		//
		//		//清除html缓存
		//		Map<String, Object> param2 = new HashMap<>();
		//		param2.put("id", id);
		//		String path2 = Const.Path.BLOG_VIEW;
		//		Topics.notifyClearHttpCache(path2, null, param2);

		String key = blogid + "";
		ICache cache = Caches.getCache(CacheConfig.BLOG_WITH_MD);
		cache.remove(key);
		Topics.notifyRemoveLocalCache(CacheConfig.BLOG_WITH_MD.getCacheName(), key);

		cache = Caches.getCache(CacheConfig.BLOG_WITH_HTML);
		cache.remove(key);
		Topics.notifyRemoveLocalCache(CacheConfig.BLOG_WITH_HTML.getCacheName(), key);

		cache = Caches.getCache(CacheConfig.BLOG);
		cache.remove(key);
		Topics.notifyRemoveLocalCache(CacheConfig.BLOG.getCacheName(), key);

	}

}
